package com.pengshun.modules.Interceptor;

import com.alibaba.fastjson.JSON;
import com.pengshun.modules.api.coal.util.SystemPath;
import com.pengshun.modules.api.mapper.PsUserInfoMapper;
import com.pengshun.modules.common.BaseResult;
import com.pengshun.modules.domain.User;
import com.pengshun.modules.jwt.JwtTokenUtil;
import com.pengshun.modules.security.Authorization;
import com.pengshun.modules.security.SelfUserDetailsService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 拦截带有头部参数token的接口
 */
@Component
@RequiredArgsConstructor
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    private String secret = "pc-api";

    private final RedisTemplate<String, String> redisTemplate;

    private final static String token = SystemPath.APP_TOKEN_PATH;

    private final PsUserInfoMapper psUserInfoMapper;

    private final  SelfUserDetailsService userDetailsService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //** spring2.0 拦截静态资源放行*
        if (handler instanceof ResourceHttpRequestHandler) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        if (method.getAnnotation(Authorization.class) == null) {
            return true;
        }
        String authHeader = request.getHeader("jwtToken");
        JwtTokenUtil util = new JwtTokenUtil();
        if (authHeader != null) {
            final String authToken = authHeader;
            Claims claims = util.parseToken(authToken);
            if (null == claims) {
                BaseResult result = new BaseResult(2, "token失效!");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(JSON.toJSONString(result));
                return false;
            }
            Long uiId = Long.valueOf(claims.get("uiId").toString());

            String redisToken = redisTemplate.opsForValue().get(token + uiId);
//               if(redisToken!=null){
//                    redisToken=redisToken.substring(1,redisToken.length()-1);
//               }
            if (StringUtils.isBlank(redisToken) || !redisToken.equals(authHeader)) {
                BaseResult result = new BaseResult(2, "token失效!");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(JSON.toJSONString(result));
                return false;
            }
            User employee = psUserInfoMapper.findUserById(uiId);
            if (employee == null) {
                BaseResult result = new BaseResult(2, "token失效!");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(JSON.toJSONString(result));
                return false;
            }
            if (claims != null && StringUtils.isNotBlank(redisToken)) {
                UserDetails userDetails = userDetailsService.loadUserByUsername(employee.getPhone());
                if (userDetails != null) {
                    UsernamePasswordAuthenticationToken authentication =
                            new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            } else {
                BaseResult result = new BaseResult(2, "token失效!");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(JSON.toJSONString(result));
                return false;
//                throw new ExpiredJwtException(null, null, "token失效");
            }
        }
        String token = request.getHeader("jwtToken");
        if (StringUtils.isEmpty(token)) {
            return false;
        }
        Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        if (null == claims) {
            return false;
        }
        request.setAttribute("uiId", claims.get("uiId"));
        request.setAttribute("name", claims.get("name"));
        request.setAttribute("phone", claims.get("phone"));
        return true;
    }
}
